package com.x2.modular.billnum.service.impl;

import com.x2.modular.billnum.entity.SysBillNumber;
import com.x2.modular.billnum.model.NowNumberVo;
import com.x2.modular.billnum.model.SysBillNumberVo;
import com.x2.modular.billnum.service.SysBillNumberGetService;
import com.x2.modular.billnum.service.SysBillNumberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 编号规则 服务实现类
 *
 * @author duangy
 * @date 2021-04-15
 */
@Service
public class SysBillNumberServiceGetImpl implements SysBillNumberGetService {
    @Autowired
    private SysBillNumberService service;

    //缓存编号
    private Map<String, NowNumberVo> seqNumMap = new HashMap<>();

    /**
     * 生成时间戳
     */
    private static String getDateScope(String format) {
        DateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date());
    }

    /**
     * 获取编号
     *
     * @param numType
     * @return
     */
    private List<SysBillNumberVo> queryNowRecord(String numType, String numDate) {
        SysBillNumberVo billNumberVo = new SysBillNumberVo();
        billNumberVo.setNumType(numType);
        billNumberVo.setNumDate(numDate);
        return service.findListBySpec(billNumberVo);
    }

    /**
     * 获取编号
     *
     * @param numType
     * @return
     */
    public  String billNumber(String numType, String scope, int batchNum) {
        return  billNumber( numType,  scope,  batchNum, 4);
    }
    /**
     * 获取编号
     *
     * @param numType 类型
     * @param scope 范围
     * @param batchNum 批量大小
     * @param numDigit 默认流水号位数
     * @return
     */
    public synchronized String billNumber(String numType, String scope, int batchNum,int numDigit) {
        //参数检查
        if (batchNum <= 0) {
            batchNum = 1;
        }
        if (numType == null || numType.trim().length() <= 0) {
            numType = "CODE";
        }
        if (scope == null || scope.trim().length() <= 0) {
            scope = "yyyyMMdd";
        }
        //当前时间戳
        String numDate = getDateScope(scope);
        NowNumberVo bean = seqNumMap.get(numType);
        Boolean isNewAdd = false;
        //if (bean == null || bean.getNumNow() % batchNum == 0) {
        //就一台服务器，不需要这么严格
        if (bean == null) {
            bean = new NowNumberVo();
            seqNumMap.put(numType, bean);
            bean.setNowDate(numDate);
            List<SysBillNumberVo> orderList = queryNowRecord(numType, numDate);
            if (orderList != null && orderList.size() > 0) {
                Integer numNow = orderList.get(0).getNumNow();
                bean.setDetailId(orderList.get(0).getId());
                if (numNow == null) {
                    numNow = 0;
                }
                if (numNow % batchNum != 0) {
                    numNow = (numNow / batchNum + 1) * batchNum;
                }
                bean.setNumNow(numNow);

            } else {
                //新增记录
                SysBillNumber entity = new SysBillNumber();
                entity.setNumName(numType);
                entity.setNumType(numType);
                entity.setNumDate(numDate);
                entity.setUpdateTime(new Date());
                entity.setNumDigit(numDigit);
                //当前流水
                entity.setNumNow(batchNum);
                BigDecimal seq = BigDecimal.valueOf(Long.valueOf(numDate));
                entity.setReservedNum1(seq);
                entity.setUpdateTime(new Date());
                service.save(entity);
                //删除旧数据
                SysBillNumberVo delCond = new SysBillNumberVo();
                delCond.setNumType(numType);
                delCond.setReservedNum1(seq);
                service.deleteOldBillNumber2(delCond);
                //初始化
                bean.setNumNow(0);
                bean.setDetailId(entity.getId());
                isNewAdd = true;


            }
        }

        //是否有缓存
        Integer numNow = bean.getNumNow();

        if (numNow % batchNum == 0 && !isNewAdd) {
            SysBillNumber entity = new SysBillNumber();
            entity.setUpdateTime(new Date());
            //默认补齐四位
            entity.setNumDigit(numDigit);
            //当前流水
            entity.setNumNow(numNow + batchNum);
            entity.setId(bean.getDetailId());
            service.updateById(entity);
        }
        numNow = numNow + 1;//流水号递增
        bean.setNumNow(numNow);
        String orderNum = this.getNewNum(numType, numDate, numDigit, numNow);
        return orderNum;
    }

    /**
     * 生成规则:编号类型+8位时间戳+补齐位数（从1开始，不够前补0）
     *
     * @param numType  编号类型
     * @param numDigit 补齐位数
     * @param numNow   最新流水编号
     * @return
     */
    private static String getNewNum(String numType, String scope, int numDigit, int numNow) {
        String newNum = "0001";
        if (numNow != 0) {
            newNum = String.format(numType + scope + "%0" + numDigit + "d", numNow);
        }
        return newNum;
    }
}
